import * as vscode from 'vscode';
import * as WebSocket from 'ws';

export interface WebSocketMessageHandler {
    (message: any): void;
}

export class WebSocketManager {
    private client: WebSocket.WebSocket | null = null;
    private reconnectTimer: NodeJS.Timeout | null = null;
    private autoReconnectEnabled = true;
    private serverAddress: string;
    private secret: string;
    private messageHandler: WebSocketMessageHandler;
    private statusCallback: (status: 'disconnected' | 'connecting' | 'connected') => void;

    constructor(
        serverAddress: string,
        secret: string,
        messageHandler: WebSocketMessageHandler,
        statusCallback: (status: 'disconnected' | 'connecting' | 'connected') => void
    ) {
        this.serverAddress = serverAddress;
        this.secret = secret;
        this.messageHandler = messageHandler;
        this.statusCallback = statusCallback;
    }

    public connect(): void {
        if (this.client) {
            this.client.close();
        }

        this.statusCallback('connecting');

        this.client = new WebSocket.WebSocket(this.serverAddress);

        this.client.on('open', () => {
            this.statusCallback('connected');
            vscode.window.showInformationMessage(`插件已连接`);
            if (this.client && this.client.readyState === WebSocket.WebSocket.OPEN) {
                this.client.send(JSON.stringify({ "cmd": "auth", "secret": this.secret }));
            }
        });

        this.client.on('message', (data) => {
            try {
                const message = JSON.parse(data.toString());
                console.log(message);
                this.messageHandler(message);
            } catch (error) {
                console.error('消息解析失败:', error);
            }
        });

        this.client.on('close', () => {
            this.statusCallback('disconnected');
            if (this.reconnectTimer) {
                clearTimeout(this.reconnectTimer);
            }
            if (this.autoReconnectEnabled) {
                this.reconnectTimer = setTimeout(() => this.connect(), 2000);
            }
        });

        this.client.on('error', (err) => {
            console.error('WebSocket连接错误:', err);
            this.statusCallback('disconnected');
            if (this.reconnectTimer) {
                clearTimeout(this.reconnectTimer);
            }
            if (this.autoReconnectEnabled) {
                this.reconnectTimer = setTimeout(() => this.connect(), 2000);
            }
        });
    }

    public disconnect(): void {
        if (this.client) {
            this.client.close();
            this.client = null;
        }
        if (this.reconnectTimer) {
            clearTimeout(this.reconnectTimer);
            this.reconnectTimer = null;
        }
        this.autoReconnectEnabled = false;
        this.statusCallback('disconnected');
    }

    public sendMessage(message: any): boolean {
        if (this.client && this.client.readyState === WebSocket.WebSocket.OPEN) {
            this.client.send(JSON.stringify(message));
            return true;
        }
        return false;
    }

    public isConnected(): boolean {
        return this.client !== null && this.client.readyState === WebSocket.WebSocket.OPEN;
    }

    public enableAutoReconnect(): void {
        this.autoReconnectEnabled = true;
    }

    public disableAutoReconnect(): void {
        this.autoReconnectEnabled = false;
    }

    public dispose(): void {
        this.disconnect();
    }
}
